package org.ddevil.data;

import java.io.Serializable;


/**
 * This interface describes the attributes objects that are used through out this toolkit.
 * An attributes object is a collection of {@link Attribute}s, which are just Database ID / Value pairings.
 * <p>
 * Implementations of this interface should enforce the constraint that a given Id maps to at most one
 * Attribute.  If a Attribute is added to the attributes object and another Attribute already exists with the
 * same Id then the new Attribute should replace the old one.<p>
 * 
 * About The Get Methods:<br>
 * There are two ways to get data from an Data object.
 * <ol>
 * <li>{@link #getDataItem(String)}<br/>This will return the actual Attribute with the given DBId.<br>
 * This is usefull if you want to keep the Name/Value paring that a Attribute gives you.</li>
 * <li>{@link #getValue(String)DBId)}<BR>This should return the value of the Attribute with the given DBId.<br>
 * This is usefull if you don't need the Name/Value pairing, but just want the given value.</li> 
 * </ol>
 * 
 * @author Eric Lundin
 * @author Rich
 */
public interface Data extends Iterable<Attribute>, Serializable {	
  
    /**
     * Check if this Criteria object contains a Data Item with the given Id.
     * 
     * @param id
     *          The Id to check for.
     *             
     * @return 
     *      true if a Data Item with that Id is in this Criteria object.
     */
	public boolean contains(String id);
	
    /**
     * Get the {@link Attribute} with the given Identifier.
     * <p>
     * There is no guarantee made as to whether changes made to
     * the returned Attribute will be reflected in this Data
     * object.  It is implementation dependant.  Thus this method
     * should only be used for reading.  All changes should be made
     * via {@link #setDataItem(String, Object)} and {@link #addDataItem(Attribute)}. 
     * 
     * @param id
     *          Id for the item we want.
     * 
     * @return  
     *      The Data Item with the given Id.
     *      <code>null</code> if no Data Item with the given Id exists. 
     */
    public Attribute getDataItem(String id);
    
    /**
     * This is a short cut for <code>getDataItem(String).getValue()</code>.
     * 
     * @param id
     *          Id for the item we want.
     * @return
     *          The value of the Attribute with the given ID.
     * 
     * @see #getDataItem(String)
     */
    public Object getValue(String id);
    
    /**
     * Add the given data item. If there is already a Attribute in the criteria
     * list then the new Attribute will replace the old one.
     * 
     * @param toAdd
     *            The Attribute to add.
     */
    public void addDataItem(Attribute toAdd);
    
    /**
     * Set the value of the Attribute with the given Id to the
     * new value.  If no item exists for the given id a new one
     * should be added.
     * 
     * @param dbId
     *          The Id of the Attribute whose value we are setting.
     *          
     * @param newValue
     *          The new value for the Attribute.
     */
    public void setDataItem(String dbId, Object newValue);    
        
    
    /**
     * Return how many items are in this Data object.
     * 
     * @return
     *      The size of this Data object.
     */
    public int size();
    
    public void copyDataFrom(Data in);

    
}
